﻿//
// Created by LiuYou on 2021/4/28.
//
#include <cstring>
#include <iostream>

//#define TEST_1
//#define TEST_2
//#define TEST_3

using String = std::string;

int main() {
#ifdef TEST_1
    char* ptrToBuffer = "wo";
    //region 注意下面这条语句, 这样只是赋值了一个字符 'p' 而已。
//    char buffer = {*ptrToBuffer};
    //endregion

    char buffer[1024];
    std::memset(buffer, 0, sizeof(buffer));
    std::strcpy(buffer, ptrToBuffer);
    std::cout << ptrToBuffer << std::endl;
    std::cout << buffer << std::endl;

    std::strcpy(buffer, "ni");
    // 修改buffer的值后并不影响之前的ptrToBuffer的值。而且因为"wo"是字符串字面值, 所以不能通过char*指针指向它, 然后修改它！！！！
    std::cout << ptrToBuffer << std::endl;
    std::cout << buffer << std::endl;

    // 这样是可以的, 符合正常思维认知。同时也是正确的。
    char str[] = "hao";
    std::cout << str << std::endl;
    str[0] = 'm';
    std::cout << str << std::endl;
#endif

#ifdef TEST_2
    char* ptrCh1 = "ni";

    char* ptrCh2 = "ni,";

    std::printf("%p\n", ptrCh1);
    std::printf("%p\n", ptrCh2);

    char* ptrCh3 = "C/C++";
    char* ptrCh4 = "C/C++";

    std::printf("%p\n", ptrCh3);
    std::printf("%p\n", ptrCh4);
#endif

#ifdef TEST_3
    {
        char buffer[1024] = "I love C/C++ forever!";
        std::string buff(buffer, sizeof(buffer));
        std::cout << buffer << std::endl;
        std::cout << buff << std::endl;
        // 输出结果为:
        // I love C/C++ forever!
        // I love C/C++ forever!

    }
    {
        char buffer[1024];
        std::memset(buffer, 0, sizeof(buffer));
        // C风格字符串不能使用 = 进行赋值。而只能通过std::strcpy进行赋值！或者就是初始化的时候指定初值, 否则之后的赋值操作都需要std::strcpy()函数！
//    buffer = "I love C/C++ forever!";
        std::strcpy(buffer, "I love C/C++ forever!");
        String buff(buffer, sizeof(buffer));
        std::cout << buffer << std::endl;
        std::cout << buff << std::endl;
        // 输出结果和上面一样:
        // 输出结果为:
        // I love C/C++ forever!
        // I love C/C++ forever!
    }
    {
        char buffer[1024];
        std::memset(buffer, 0, sizeof(buffer));
        std::strcpy(buffer, "I love C/C++ forever!");
        String buff(buffer, std::strlen(buffer));
        std::cout << buffer << std::endl;
        std::cout << buff << std::endl;
        // 输出结果两个是一样的:
        // I love C/C++ forever!
        // I love C/C++ forever!
    }
    {
        char buffer[1024];
        std::memset(buffer, 0, sizeof(buffer));
        std::strcpy(buffer, "go");
        String buff(buffer);
        std::cout << buffer << std::endl;
        std::cout << buff << std::endl;
    }
#endif


// 不行C++对中文的支持好差啊。
#ifdef TEST_4
    //    std::cout.imbue(std::locale("zh_CN"));
    //    std::cout.imbue(std::locale("zh_CN.GB18030"));
    //    std::cout.imbue(std::locale("zh_CN.GBK"));
    //    std::cout.imbue(std::locale("chs"));
    //    setlocale(LC_ALL, "chs");

        char16_t hanZi = u'你';
        std::cout << hanZi << std::endl;
        std::printf("%c\n", hanZi);

        char32_t hanZi2 = U'中';
        std::cout << hanZi2 << std::endl;
        std::printf("%c\n", hanZi2);

        wchar_t hanZi3 = L'国';
        std::cout << hanZi3 << std::endl;
        std::printf("%c\n", hanZi3);
#endif

#ifdef TEST_5
    {
        String str("冲冲冲, 凑弟弟！");
        std::cout << str << std::endl;
        char buffer[1024];
        std::memset(buffer, 0, sizeof(buffer));
        std::strcpy(buffer, str.c_str());
//    std::strcpy(buffer, str.data());
        std::cout << str << std::endl;
        std::cout << buffer << std::endl;
        std::strcat(buffer, "他来了，他来了");
        std::cout << buffer << std::endl;
        std::cout << str << std::endl;
    }
    std::cout << "=================================" << std::endl;
    {
        String str("冲冲冲, 凑弟弟！");
        std::cout << str << std::endl;
        char buffer[1024];
        std::memset(buffer, 0, sizeof(buffer));
        std::cout << "str.copy(buffer, sizeof(buffer)): " << str.copy(buffer, sizeof(buffer)) << std::endl;
        std::cout << "str.copy(buffer, std::strlen(str.c_str())): " << str.copy(buffer, std::strlen(str.c_str()))
                  << std::endl;
        std::cout << str << std::endl;
        std::cout << buffer << std::endl;
        std::strcat(buffer, "他来了，他来了");
        std::cout << buffer << std::endl;
        std::cout << str << std::endl;
    }
#endif

#ifdef TEST_6
    {
        char buffer[] = "collection";
        String str(buffer);
        std::cout << "str.max_size(): " << str.max_size() << std::endl;
        std::cout << "str.capacity(): " << str.capacity() << std::endl;
        std::cout << "str.size(): " << str.size() << std::endl;
        std::cout << "str.length(): " << str.length() << std::endl;
    }
    std::cout << std::endl;
    {
        char buffer[] = "c";
        String str(buffer);
        std::cout << "str.max_size(): " << str.max_size() << std::endl;
        std::cout << "str.capacity(): " << str.capacity() << std::endl;
        std::cout << "str.size(): " << str.size() << std::endl;
        std::cout << "str.length(): " << str.length() << std::endl;
    }
    // TODO 注意: 上面两个例子可以得出string有拥有的容量就是分配给字符串的长度。
    std::cout << std::endl;
    {
        char buffer[] = "c";
        String str;
        // reserve memory for 1024 characters
        // 预留(保留)1024个字符的内存。
        // TODO 注意: 成员方法reserve()用来避免重分配行为, 它使得用户可以预留一定容量, 并确保该容量用尽之前reference一直保持有效。
        str.reserve(1024);
        str.assign(buffer);
        std::cout << "str.max_size(): " << str.max_size() << std::endl;
        std::cout << "str.capacity(): " << str.capacity() << std::endl;
        std::cout << "str.size(): " << str.size() << std::endl;
        std::cout << "str.length(): " << str.length() << std::endl;
    }
    std::cout << std::endl;
    {
        char buffer[] = "collection";
        String str;
        // reserve memory for 1024 characters
        // 预留(保留)1024个字符的内存。
        // TODO 注意: 成员方法reserve()用来避免重分配行为, 它使得用户可以预留一定容量, 并确保该容量用尽之前reference一直保持有效。
        str.reserve(1024);
        str.assign(buffer);
        std::cout << "str.max_size(): " << str.max_size() << std::endl;
        std::cout << "str.capacity(): " << str.capacity() << std::endl;
        std::cout << "str.size(): " << str.size() << std::endl;
        std::cout << "str.length(): " << str.length() << std::endl;
        // 如果实参小于现有字符数, 一般是缩减到可以放下字符串的长度(不包括'\0')。
//        str.reserve(2);
        // 想要缩减容量至某个目标, 但是reserve()方法并不保证可以如愿。虽然本测试中str.reserve(100);如愿了。
        str.reserve(100);
        // 下面这两个是一样的, 不过shrink_to_fit()方法是C++11加入的。在该测试中这两个方法都可以使容量缩减为str.size()的长度。
        // C++标准规定: 只有reserve()或shrink_to_fit()方法调用时, 容量才 有可能 缩减。
//        str.reserve();
//        str.shrink_to_fit();
        std::cout << "str.max_size(): " << str.max_size() << std::endl;
        std::cout << "str.capacity(): " << str.capacity() << std::endl;
        std::cout << "str.size(): " << str.size() << std::endl;
        std::cout << "str.length(): " << str.length() << std::endl;
        std::cout << str << std::endl;
    }
#endif

#ifdef TEST_7
    char buffer[1024] = "effective";
    std::string str(buffer);
    std::cout << "str.length(): " << str.length() << std::endl;
    std::cout << "str.capacity(): " << str.capacity() << std::endl;
    std::cout << str << std::endl;

    str.resize(10, 'a');
    std::cout << "str.length(): " << str.length() << std::endl;
    std::cout << "str.capacity(): " << str.capacity() << std::endl;
    std::cout << str << std::endl;

//    str.resize(100, '\0');
    str.resize(100, 'a');
    std::cout << "str.length(): " << str.length() << std::endl;
    std::cout << "str.capacity(): " << str.capacity() << std::endl;
    std::cout << str << std::endl;

    str.resize(2);
    std::cout << "str.length(): " << str.length() << std::endl;
    std::cout << "str.capacity(): " << str.capacity() << std::endl;
    std::cout << str << std::endl;
#endif

#ifdef TEST_8
    char buffer[1024] = "effective";
    std::string str(buffer);
    std::cout << "buffer: " << buffer << std::endl;
    std::cout << "str: " << str << std::endl;
    std::cout << "str.size(): " << str.size() << std::endl;
    std::cout << "str.capacity(): " << str.capacity() << std::endl;
    // 这两个函数是等效的。
    str.clear();
//    str.erase();
    std::cout << "buffer: " << buffer << std::endl;
    std::cout << "str: " << str << std::endl;
    std::cout << "str.size(): " << str.size() << std::endl;
    // TODO  这里输出9(即effective的字符个数)是我没想到的。原因: 我不知道。
    std::cout << "str.capacity(): " << str.capacity() << std::endl;
#endif


    return 0;
}